﻿#include <vtkTransform.h>
#include <vtkMath.h>
#include <vtkLine.h>
#include <vtkPlane.h>

using namespace std;

void calcAngle();

/// 计算两个vector的夹角
void calcAngle()
{
    double v1[3] = {1, 1, 0};
    double v2[3] = {1, 0, 0};
    double angle;

    // 计算 <v1, v2>
    angle = vtkMath::AngleBetweenVectors(v1, v2);
    std::cout << "angle clockwise:" << vtkMath::DegreesFromRadians(angle) << std::endl;

    // 计算 <v2, v1>
    angle = vtkMath::AngleBetweenVectors(v2, v1);
    std::cout << "angle couter clockwise:" << vtkMath::DegreesFromRadians(angle) << std::endl;

    // 结论是 没有正反方向
}

void calVector()
{
    double v1[3] = {1, 1, 0};
    double v2[3] = {2, 0, 0};
    double v3[3];

    vtkMath::Cross(v1, v2, v3);
    vtkMath::Normalize(v3);

    std::cout << "cross value v1xv2= " << v3[0] << ", " << v3[1] << ", " << v3[2] << std::endl;
}

/// This function computes the distance from a point to a line. 具体见
/// https://lorensen.github.io/VTKExamples/site/Cxx/SimpleOperations/DistancePointToLine/
inline void distancePointToLine()
{
    double lineP0[3] = {0.0, 0.0, 0.0};
    double lineP1[3] = {2.0, 0.0, 0.0};

    double p0[3] = {1.0, 0, 0};
    double p1[3] = {1.0, 2.0, 0};

     /*
     vtkSmartPointer<vtkLine> line =
       vtkSmartPointer<vtkLine>::New();
     line->GetPoints()->SetPoint(0, lineP0);
     line->GetPoints()->SetPoint(0, lineP1);
     */

     {
     double dist0 = vtkLine::DistanceToLine(p0, lineP0, lineP1);
     std::cout << "Dist0: " << dist0 << std::endl;

     // 返回的是距离的平方
     double dist1 = vtkLine::DistanceToLine(p1, lineP0, lineP1);
     std::cout << "Dist1: " << dist1 << std::endl;
     }

    {
        double t;
        double closest[3];
        double dist0 = vtkLine::DistanceToLine(p0, lineP0, lineP1, t, closest);
        std::cout << "Dist0: " << dist0 << " closest point: " << closest[0] << " " << closest[1] << " " << closest[2] << std::endl;

        double dist1 = vtkLine::DistanceToLine(p1, lineP0, lineP1, t, closest);
        std::cout << "Dist1: " << dist1 << " closest point: " << closest[0] << " " << closest[1] << " " << closest[2] << std::endl;
    }
}

/// This function computes the distance from a point to plane
/// ref: https://lorensen.github.io/VTKExamples/site/Cxx/SimpleOperations/ProjectPointPlane/
inline void distancePointToPlane()
{
    vtkSmartPointer<vtkPlane> plane =
        vtkSmartPointer<vtkPlane>::New();
    plane->SetOrigin(0.0, 0.0, 0.0);
    plane->SetNormal(0.0, 0.0, 1.0);

    double p[3] = {23.1, 54.6, 9.2};
    double origin[3] = {0.0, 0.0, 0.0};
    double normal[3] = {0.0, 0.0, 1.0};
    double projected[3];

    plane->ProjectPoint(p, origin, normal, projected);

    std::cout << "Projected: " << projected[0] << " "
              << projected[1] << " " << projected[2] << std::endl;

    double dist0 = vtkPlane::DistanceToPlane(p, normal, origin);
    std::cout << "Dist0: " << dist0 << std::endl;

    // 三点到面的距离
}

int main(int, char *[])
{
    cout << "1. 计算两个vector的角度" << endl;
    calcAngle();  // 计算两个vector的夹角

    cout << "2. 点到线的距离" << endl;
    distancePointToLine();

    cout << "3. 点到面的距离" << endl;
    distancePointToPlane();

    return EXIT_SUCCESS;
}
